#include <iostream>
#include <string>
#include <math.h>

// 

// 现金收费抽象类
class CashSuper {
    public:
    virtual double acceptCash(double money) {
        return 0.0;
    }
};

// 正常收费子类
class CashNormal : public CashSuper{
    public:
    double acceptCash(double money) {
        return money;
    }
};

// 打折收费子类
class CashRebate : public CashSuper {
    public:
    CashRebate(double money_rebate):money_rebate_(money_rebate) {}
    double acceptCash(double money) {
        return money * money_rebate_;
    }
    private:
    double money_rebate_;
};

// 返利收费子类
class CashReturn : public CashSuper {
    public:
    CashReturn(double money_condition,double money_return): money_condition_(money_condition),
                                                            money_return_(money_return){}
    double acceptCash(double money) {
        double result = money;
        if(money >= money_condition_) {
            result = money - floor(money / money_condition_) * money_return_;
        }
        return result;
    }
    private:
    double money_condition_;
    double money_return_;
};


// 现金收费工厂类
class CashFactory {
    public:
    CashFactory():cs(nullptr){}
    ~CashFactory() {
        if(cs != nullptr) {
            delete cs;
            cs = nullptr;
        }
    }
    CashSuper* createCashAcccept(char type) {
        if(type == 'A') {
            cs = new CashNormal();
        }
        else if(type == 'B') {
            cs = new CashRebate(0.8);
        }
        else if(type == 'C'){
            cs = new CashReturn(300,100);
        }
        return cs;
    }
    private:
    CashSuper* cs;
};

int main() {
    char type;
    CashFactory cf;
    CashSuper* cs = nullptr;
    double result_cash;

    std::cout << "Hello design patterns" << std::endl;
    std::cout << "Please input your cash strategy type:" << std::endl;
    std::cout << "A:正常收费模式 " << "B:打折模式 " << "C:返现模式  ";
    std::cin >> type;
    cs = cf.createCashAcccept(type);
    result_cash = cs->acceptCash(300);
    std::cout << "实际收费：" << result_cash << std::endl;
    return 0;
}